package gov.gfbzb.advice.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hankcs.hanlp.HanLP;
import gov.gfbzb.advice.controller.dto.KeyValueDTO;
import gov.gfbzb.advice.entity.Advice;
import gov.gfbzb.advice.service.IAdviceService;
import gov.gfbzb.advice.service.IJobService;
import jakarta.annotation.PostConstruct;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Log4j2
@Service
public class JobServiceImpl implements IJobService {

    @Value("${gfbzb.env}")
    private String env;

    @Autowired
    private IAdviceService adviceService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    @PostConstruct
    @Async("jobExecutor")
    @Scheduled(cron = "0 0 0 * * ?")
    public void generateKeyWord() {
        log.info("定时任务————生成词云————开始执行...");
        QueryWrapper<Advice> queryWrapper = new QueryWrapper<>();
        // 未被删除
        queryWrapper.eq("is_delete", 0);
        // 审核通过
        queryWrapper.eq("question_status", 1);
        List<Advice> list = adviceService.list(queryWrapper);
        // 所有的标题和内容
        List<String> titleAndContent = list.stream().map(advice -> advice.getTitle() + advice.getContent()).toList();

        Map<String, Integer> keywordFrequency = new HashMap<>();
        titleAndContent.forEach(content -> {
            List<String> keywords = HanLP.extractKeyword(content, 5);
            for (String keyword : keywords) {
                keywordFrequency.put(keyword, keywordFrequency.getOrDefault(keyword, 0) + 1);
            }
        });

        redisTemplate.opsForValue().set(env+"KeyWord", keywordFrequency);
        log.info("定时任务————生成词云————执行完毕！");
    }

    @Override
    @PostConstruct
    @Async("jobExecutor")
    @Scheduled(cron = "0 0 0 * * ?")
    public void getCountyQuestionAllCount(){
        log.info("定时任务————各区县咨询总问题量————开始执行...");
        List<KeyValueDTO> countyQuestionCount = getCountyQuestionCount(null);
        redisTemplate.opsForValue().set(env+"CountyQuestionAllCount", countyQuestionCount);
        log.info("定时任务————各区县咨询总问题量————执行完毕！");
    }

    @Override
    @PostConstruct
    @Async("jobExecutor")
    @Scheduled(cron = "0 0 0 * * ?")
    public void getCountyNoPassQuestionCount(){
        log.info("定时任务————各区县咨询待审核问题量————开始执行...");
        List<KeyValueDTO> countyQuestionCount = getCountyQuestionCount(false);
        redisTemplate.opsForValue().set(env+"CountyNoPassQuestionCount", countyQuestionCount);
        log.info("定时任务————各区县咨询待审核问题量————执行完毕！");
    }

    @Override
    @PostConstruct
    @Async("jobExecutor")
    @Scheduled(cron = "0 0 0 * * ?")
    public void getCountyPassQuestionCount(){
        log.info("定时任务————各区县咨询已审核问题量————开始执行...");
        List<KeyValueDTO> countyQuestionCount = getCountyQuestionCount(true);
        redisTemplate.opsForValue().set(env+"CountyPassQuestionCount", countyQuestionCount);
        log.info("定时任务————各区县咨询已审核问题量————执行完毕！");
    }


    @Async("jobExecutor")
    public List<KeyValueDTO> getCountyQuestionCount(Boolean isPass){
        QueryWrapper<Advice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);
        if (isPass!=null){
            // 已审核
            if (isPass){
                queryWrapper.eq("question_status", 1);
            }else {
                // 待审核、已驳回
                queryWrapper.and(wrapper -> {
                    wrapper.eq("question_status", 2)
                            .or()
                            .eq("question_status", 0);
                });
            }
        }
        List<Advice> adviceList = adviceService.list(queryWrapper);
        // 获取各区县出现的次数 Map
        Map<String, Integer> countMap = new HashMap<>();

        for (Advice advice : adviceList) {
            String county = advice.getCounty();
            countMap.put(county, countMap.getOrDefault(county, 0) + 1);
        }

        return countMap.entrySet().stream()
                .map(entry -> new KeyValueDTO(entry.getKey(), entry.getValue()))
                .sorted(Comparator.comparingInt(KeyValueDTO::getValue).reversed())
                .collect(Collectors.toList());
    }
}
